#pragma once

namespace xpam
{
    namespace math
    {
        template<class T, class T1>
        class filter
        {
            int _src_sx, _src_sy, _dst_sx, _dst_sy;
            std::vector<int> _indexes;
            T1 _k;
            std::vector<T1> _kk;
            T1 _s;
        public:
            filter(int src_sx, int src_sy, int dst_sx, int dst_sy)
            {
                _src_sx = src_sx;
                _src_sy = src_sy;
                _dst_sx = dst_sx;
                _dst_sy = dst_sy;
                _k = 1;
                _s = 0;
            }
    
            void reset_indexes()
            {
                _indexes.resize(0);
                _kk.resize(0);
            }

            void add_index(int x, int y, T1 k)
            {
                _indexes.push_back(x * _src_sx + y * _src_sy);
                _kk.push_back(k);
            }

            void set_k(T1 k)
            {
                _k = k;
            }

            void set_s(T1 s)
            {
                _s = s;
            }

            void go(T * src, T * dst, int width, int height)
            {
                int n = (int)_indexes.size();
                for (int y = 0; y < height; y++)
                {
                    T * psrc = src + y * _src_sy;
                    T * pdst = dst + y * _dst_sy;
                    for (int x = 0; x < width; x++)
                    {
                        T1 tmp = 0;
                        for (int i = 0; i < n; i++)
                        {
                            tmp += *(psrc + _indexes[i]) * _kk[i];
                        }
                        (*pdst) = (T)(tmp / _k + _s);
                        psrc += _src_sx;
                        pdst += _dst_sx;
                    }
                }
            }
        };
    }
}